package com.skiving.cloud.filter;

import cn.dev33.satoken.exception.*;
import com.skiving.cloud.common.utils.ReturnT;
import io.vertx.core.buffer.Buffer;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpStatus;
import org.noear.snack.ONode;
import org.noear.solon.annotation.Component;
import org.noear.solon.cloud.gateway.CloudGatewayFilter;
import org.noear.solon.cloud.gateway.exchange.ExContext;
import org.noear.solon.cloud.gateway.exchange.ExFilterChain;
import org.noear.solon.rx.Completable;
import org.noear.solon.rx.SimpleSubscriber;

@Component(index = -98)
@Slf4j
public class GlobalExceptionFilter implements CloudGatewayFilter {

    /**
     * 过滤
     *
     * @param ctx   交换上下文
     * @param chain 过滤链
     */
    @Override
    public Completable doFilter(ExContext ctx, ExFilterChain chain) {
        return Completable.create(emitter -> {
            chain.doFilter(ctx).subscribe(new SimpleSubscriber<>() {
                @Override
                public void onError(Throwable e) {
                    log.error(e.getMessage(), e);
                    if (e instanceof NotLoginException ee) {    // 如果是未登录异常
                        String resultStr = ONode.stringify(ReturnT.error(HttpStatus.SC_UNAUTHORIZED, ee.getMessage()));
                        ctx.newResponse().body(Buffer.buffer(resultStr));
                    } else if (e instanceof NotRoleException ee) {        // 如果是角色异常
                        String resultStr = ONode.stringify(ReturnT.error(HttpStatus.SC_FORBIDDEN, ee.getMessage()));
                        ctx.newResponse().body(Buffer.buffer(resultStr));
                    } else if (e instanceof NotPermissionException ee) {    // 如果是权限异常
                        String resultStr = ONode.stringify(ReturnT.error(HttpStatus.SC_FORBIDDEN, ee.getMessage()));
                        ctx.newResponse().body(Buffer.buffer(resultStr));
                    } else if (e instanceof DisableServiceException ee) {    // 如果是被封禁异常
                        String resultStr = ONode.stringify(ReturnT.error(HttpStatus.SC_FORBIDDEN, "账号被封禁：" + ee.getDisableTime()  + "秒后解封"));
                        ctx.newResponse().body(Buffer.buffer(resultStr));
                    } else {    // 普通异常, 输出：500 + 异常信息
                        String resultStr = ONode.stringify(ReturnT.error(HttpStatus.SC_INTERNAL_SERVER_ERROR, e.getMessage()));
                        ctx.newResponse().body(Buffer.buffer(resultStr));
                    }
                    emitter.onComplete();
                }

                @Override
                public void onComplete() {
                    emitter.onComplete();
                }
            });
        });
    }
}
